package com.yunhe.authority.controller.authority;

import com.yunhe.authority.domain.authority.EmployeeUser;
import com.yunhe.authority.domain.authority.ProejctRoleOrg;
import com.yunhe.authority.domain.authority.User;
import com.yunhe.authority.service.authority.RoleService;
import com.yunhe.authority.service.authority.UserService;
import com.yunhe.common.annotation.OperationRecord;
import com.yunhe.common.constant.SystemConsts;
import com.yunhe.common.model.PageParam;
import com.yunhe.authority.domain.authority.Role;
import com.yunhe.common.exception.ArgumentErrorException;
import com.yunhe.common.exception.ObjectNotFoundException;
import com.yunhe.common.exception.UniqueConstraintsException;
import com.yunhe.common.model.ResultObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

/**
 * 角色Controller
 * @author liuronglei
 */
@Api(value = "role",description = "角色维护", tags = {"Authority_Role"})
@RestController
@RequestMapping("/roles")
public class RoleController {

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserService userService;

    /**
     * 新增角色
     * @param parentId 父角色id
     * @param stationId 项目id
     * @param firmId    单位id
     * @param role      角色对象
     * @return
     * @throws ArgumentErrorException
     * @throws UniqueConstraintsException
     * @throws ObjectNotFoundException
     */
    @ApiOperation("新增角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "parentId", value = "父角色ID", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "stationId", value = "项目ID", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "firmId", value = "单位ID", required = false, dataType = "long", paramType = "query")
    })
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    @OperationRecord(menu = "角色管理", actionType = SystemConsts.ACTION.ADD)
    public ResponseEntity<ResultObject> post(@RequestParam(value = "parentId", required = false) Long parentId,
                                             @RequestParam(value = "stationId", required = false) Long stationId,
                                             @RequestParam(value = "firmId",required = false) Long firmId,
                                             @RequestBody Role role)
            throws ArgumentErrorException, UniqueConstraintsException, ObjectNotFoundException {
        Role newRole = roleService.createRole(parentId, stationId, firmId, role);
        return new ResponseEntity<>(new ResultObject<>(newRole), HttpStatus.OK);
    }

    /**
     * 根据角色IDS删除角色
     * @param ids 角色IDS
     */
    @ApiOperation("根据角色IDS删除角色,支持批量删除")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "角色ID列表", required = true, dataType = "String", paramType = "path")
    })
    @RequestMapping(value = "/delete/{ids}", method = RequestMethod.DELETE)
    @OperationRecord(menu = "角色管理", actionType = SystemConsts.ACTION.DELETE)
    public ResponseEntity<ResultObject> deleteByIds(@PathVariable("ids") String ids)
            throws ArgumentErrorException {
        roleService.deleteRoleByIds(ids);
        return new ResponseEntity<>(new ResultObject<>("success"), HttpStatus.OK);
    }

    /**
     * 更新角色
     * @param id 角色ID
     * @param role 角色对象
     */
    @ApiOperation("更新角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/update/{id}", method = RequestMethod.PUT)
    @OperationRecord(menu = "角色管理", actionType = SystemConsts.ACTION.EDIT)
    public ResponseEntity<ResultObject> put(@PathVariable("id") Long id,
                                            @RequestBody Role role)
            throws ArgumentErrorException, ObjectNotFoundException, UniqueConstraintsException {
        role.setId(id);
        Role newRole = roleService.updateRole(role);
        return new ResponseEntity<>(new ResultObject<>(newRole), HttpStatus.OK);
    }

    /**
     * 根据角色ID获得角色
     * @param id 角色ID
     */
    @ApiOperation("根据角色ID获得角色")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", required = true, dataType = "long", paramType = "path")
    })
    @RequestMapping(value = "/searchById/{id}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> get(@PathVariable("id") Long id) {
        Role role = roleService.findByRoleId(id);
        return new ResponseEntity<>(new ResultObject<>(role), HttpStatus.OK);
    }

    /**
     * 根据条件获得角色列表
     */
    @ApiOperation("根据条件获得角色列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "keywords", value = "关键词", dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> search(@RequestParam(value = "keywords", required = false) String keywords,
                                               @ModelAttribute PageParam pageParam) {
        Page<Role> results = roleService.findAllRoles(keywords, pageParam);
        return new ResponseEntity<>(new ResultObject<>(results), HttpStatus.OK);

    }


    /*********************2021**********************/
    /**
     * 根据项目ID或单位ID获得用户列表(分页)
     * @param stationId 项目ID
     * @param firmId 单位ID
     * @param keywords 关键词
     */
    @ApiOperation("根据项目ID或单位ID获得用户列表(分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "stationId", value = "项目ID", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "firmId", value = "单位ID", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "keywords", value = "关键词", required = false, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/searchByStationOrFirm", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> searchByStationOrFirm(@RequestParam(value = "keywords", required = false) String keywords,
                                                              @RequestParam(value = "stationId", required = false) Long stationId,
                                                              @RequestParam(value = "firmId", required = false) Long firmId,
                                                              @ModelAttribute PageParam pageParam) {
        Page<Role> rolePage = roleService.findRolesByStationIdOrFirmIdForPage(stationId, firmId, keywords, pageParam);
        return new ResponseEntity<>(new ResultObject<>(rolePage), HttpStatus.OK);
    }

    /**
     * 根据项目ID或单位ID获得用户列表(不分页)
     * @param stationId 项目ID
     * @param firmId 单位ID
     */
    @ApiOperation("根据项目ID或单位ID获得用户列表(不分页)")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "stationId", value = "项目ID", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "firmId", value = "单位ID", required = false, dataType = "long", paramType = "query")
    })
    @RequestMapping(value = "/searchByStationOrFirmNotPage", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> searchByStationOrFirmNotPage(@RequestParam(value = "stationId", required = false) Long stationId,
                                                                     @RequestParam(value = "firmId", required = false) Long firmId) {
        List<Role> roleList = roleService.findRolesByStationIdOrFirmId(stationId, firmId);
        return new ResponseEntity<>(new ResultObject<>(roleList), HttpStatus.OK);
    }

    /**
     * 角色绑定/绑定菜单
     * @param menuIds 菜单ID列表
     * @param roleId 角色ID
     */
    @ApiOperation("角色绑定/绑定菜单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", required = true, dataType = "long", paramType = "path"),
            @ApiImplicitParam(name = "menuIds", value = "菜单ID列表", required = false, dataType = "String", paramType = "query"),
            @ApiImplicitParam(name = "systemMenuCategory", value = "菜单类型", required = true, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/{roleId}/roles", method = RequestMethod.POST)
    public ResponseEntity<ResultObject> roleBindMenus(@PathVariable("roleId") Long roleId,
                                                      @RequestParam(value = "menuIds", required = false) String menuIds,
                                                      @RequestParam(value = "systemMenuCategory", required = true) String systemMenuCategory)
            throws ArgumentErrorException, ObjectNotFoundException {
        roleService.roleBindMenus(roleId, menuIds,systemMenuCategory);
        return new ResponseEntity<>(new ResultObject<>("success"), HttpStatus.OK);
    }


    /**
     * 根据当前登录人以及选择的项目确定对应的角色以及当前项目的组织以及记录当前访问的项目
     * @param stationId 项目ID
     * @param firmId 单位ID
     */
    @ApiOperation("根据当前登录人以及选择的项目确定对应的角色以及当前项目的组织以及记录当前访问的项目")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "stationId", value = "项目ID", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "firmId", value = "单位ID", required = false, dataType = "long", paramType = "query")
    })
    @RequestMapping(value = "/getRoleByLoginUser", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> getRoleByLoginUser(@RequestParam(value = "stationId", required = false) Long stationId,
                                                           @RequestParam(value = "firmId", required = false) Long firmId) throws ArgumentErrorException {
        ProejctRoleOrg proejctRoleOrg = roleService.getRoleByLoginUser(stationId, firmId);
        return new ResponseEntity<>(new ResultObject<>(proejctRoleOrg), HttpStatus.OK);
    }

    /**
     * 根据角色ID获得用户列表
     * @param id 角色ID
     * @param keywords 关键词
     * @date 2021-06-18
     */
    @ApiOperation("根据角色ID获得用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", required = true, dataType = "long", paramType = "path"),
            @ApiImplicitParam(name = "keywords", value = "关键词", required = false, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/findUsersById/{id}", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> findUsersById(@PathVariable(value = "id") Long id,
                                                      @RequestParam(value = "keywords", required = false) String keywords,
                                                      @ModelAttribute PageParam pageParam) {
        Page<User> users = roleService.findUsersByIdAndCondition(id, keywords ,pageParam);
        return new ResponseEntity<>(new ResultObject<>(users), HttpStatus.OK);
    }

    /**
     * 根据角色ID获得用户列表
     * @param id 角色ID
     * @param stationId 虚拟园区id
     * @param keywords 关键词
     * @date 2021-06-29
     */
    @ApiOperation("根据角色ID和(虚拟园区id或单位id)获得用户列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "角色ID", required = true, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "stationId", value = "虚拟园区id", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "firmId", value = "单位id", required = false, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "keywords", value = "关键词", required = false, dataType = "String", paramType = "query")
    })
    @RequestMapping(value = "/findUsersByIdAndStationIdOrFirmId", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> findUsersByIdAndStationIdOrFirmId(@RequestParam(value = "id", required = true) Long id,
                                                                  @RequestParam(value = "stationId", required = false) Long stationId,
                                                                  @RequestParam(value = "firmId", required = false) Long firmId,
                                                                  @RequestParam(value = "keywords", required = false) String keywords,
                                                                  @ModelAttribute PageParam pageParam) {
        Page<EmployeeUser> users = userService.getUserByStationIdOrFirmId(id, stationId, firmId, keywords ,pageParam);
        return new ResponseEntity<>(new ResultObject<>(users), HttpStatus.OK);
    }

    @ApiOperation("移除用户与角色的关系")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID", required = true, dataType = "long", paramType = "query"),
            @ApiImplicitParam(name = "userId", value = "用户id", required = true, dataType = "long", paramType = "query")
    })
    @RequestMapping(value = "/unbindUserAndRole", method = RequestMethod.GET)
    public ResponseEntity<ResultObject> unbindUserAndRole(@RequestParam(value = "roleId", required = true) Long roleId,
                                                          @RequestParam(value = "userId", required = true) Long userId) {
        userService.unbindUserAndRole(roleId, userId);
        return new ResponseEntity<>(new ResultObject<>(), HttpStatus.OK);
    }
}